package team.seekers.hula.course.structure.section.service;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.hula.common.entity.result.ApiExceptionEnum;
import team.seekers.hula.common.entity.result.ApiException;
import team.seekers.hula.course.resource.exam.entity.vo.ExamInfoVO;
import team.seekers.hula.course.resource.exam.service.ExamService;
import team.seekers.hula.course.resource.examSubmit.service.ExamRecordService;
import team.seekers.hula.course.resource.sectionContent.dao.SectionContentDao;
import team.seekers.hula.course.resource.sectionContent.entity.dto.SectionContentDTO;
import team.seekers.hula.course.resource.sectionContent.entity.vo.SectionContentVO;
import team.seekers.hula.course.resource.sectionContent.service.SectionContentService;
import team.seekers.hula.course.resource.sectionTalk.entity.vo.SectionTalkListVO;
import team.seekers.hula.course.resource.sectionTalk.service.SectionTalkService;
import team.seekers.hula.course.structure.chapter.dao.ChapterDao;
import team.seekers.hula.course.structure.chapter.entity.dao.ChapterDO;
import team.seekers.hula.course.structure.section.dao.SectionDao;
import team.seekers.hula.course.structure.section.entity.dao.SectionDO;
import team.seekers.hula.course.structure.section.entity.dto.SectionDTO;
import team.seekers.hula.course.structure.section.entity.dto.SectionListDTO;
import team.seekers.hula.course.structure.section.entity.vo.SectionInfoVO;
import team.seekers.hula.course.structure.section.entity.vo.SectionStudyVO;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * date: 2022/5/8 21:59
 *
 * @author GH
 * QQ 1124813753
 */
@Service
public class SectionService {

    @Autowired
    private SectionDao sectionDao;

    @Autowired
    private SectionProgressService sectionProgressService;

    @Autowired
    private ChapterDao chapterDao;

    @Autowired
    private SectionContentDao sectionContentDao;

    @Autowired
    private SectionContentService sectionContentService;

    @Autowired
    private ExamService examService;

    @Autowired
    private ExamRecordService examRecordService;


    @Autowired
    private SectionTalkService sectionTalkService;

    public List<SectionListDTO> querySimpleSectionsByChapterId(String chapterId) {
        List<SectionDO> sectionDOS = sectionDao.lambdaQuery().select(
                SectionDO::getId,
                SectionDO::getOpen,
                SectionDO::getName
        ).eq(SectionDO::getChapterId, chapterId).list();
        return sectionDOS.stream().map(o1 ->
                SectionListDTO.builder()
                        .id(o1.getId())
                        .name(o1.getName())
                        .contents(sectionContentService.querySectionContentsBySectionId(o1.getId()))
                        .build()).collect(Collectors.toList());
    }

    public List<SectionListDTO> queryDetailSectionsByChapterId(String chapterId, String userId) {
        List<SectionDTO> sections = SectionDO.toDTOList(sectionDao.lambdaQuery().select(
                SectionDO::getId,
                SectionDO::getType,
                SectionDO::getName
        ).eq(SectionDO::getChapterId, chapterId).orderByAsc(SectionDO::getSequence).list());

        ArrayList<String> sectionIds = new ArrayList<>();
        for (SectionDTO section : sections) {
            sectionIds.add(section.getId());
        }


        Map<String,Integer> mapProgress =  sectionProgressService.mapProgressBySectionIds(sectionIds,userId);

        return sections.stream().map(o1 ->
                SectionListDTO.builder()
                        .id(o1.getId())
                        .name(o1.getName())
                        .type(o1.getType())
                        .progress(mapProgress.get(o1.getId()))
                        .contents(sectionContentService.querySectionContentsBySectionIdWithStatus(o1.getId(), userId))
                        .build()).collect(Collectors.toList());
    }

    public List<SectionListDTO> queryDetailSectionsByChapterId(List<Long> sectionIds) {
        List<SectionDTO> sections = SectionDO.toDTOList(sectionDao.lambdaQuery().select(
                SectionDO::getId,
                SectionDO::getName
//                SectionDO::getContents
        ).in(SectionDO::getId, sectionIds).list());
        return sections.stream().map(o1 ->
                SectionListDTO.builder()
                        .id(o1.getId())
                        .name(o1.getName())
                        .contents(sectionContentService.queryByIds(o1.getContentIds()))
                        .build()).collect(Collectors.toList());
    }

    public List<String> getAttachChapterAllSectionIdsById(String sectionId) {
        String chapterId = sectionDao.lambdaQuery().select(
                SectionDO::getChapterId
        ).eq(SectionDO::getId, sectionId).one().getChapterId();

        List<SectionDO> list = sectionDao.lambdaQuery().select(
                SectionDO::getId
        ).eq(SectionDO::getChapterId, chapterId).list();

        ArrayList<String> sectionIds = new ArrayList<>();
        for (SectionDO sectionDO : list) {
            sectionIds.add(sectionDO.getId());
        }
        return sectionIds;
    }

    public String getAttachChapterNameById(String sectionId) {
        String chapterId = sectionDao.lambdaQuery().select(
                SectionDO::getChapterId
        ).eq(SectionDO::getId, sectionId).one().getChapterId();

        return chapterDao.lambdaQuery().select(
                ChapterDO::getName
        ).eq(ChapterDO::getId,chapterId).one().getName();
    }


    public List<SectionDO> getSectionDOsByCourseId(String courseId) {
        return null;
    }

    public SectionStudyVO getStudyInfo(String id, String userId) {
        SectionDO sectionDO = sectionDao.getById(id);
        SectionInfoVO sectionInfoVO = new SectionInfoVO();
        BeanUtils.copyProperties(sectionDO,sectionInfoVO);


        if(sectionDO.getType() == 0){
            // 富文本
            SectionContentDTO contentBySectionId = sectionContentService.getBindContentBySectionId(id);
            sectionInfoVO.setLinkId(contentBySectionId.getId());
            sectionInfoVO.setContent(contentBySectionId.getContent());
        }else{
            // 考试
            ExamInfoVO infoVO = examService.getBindInfoVOByExamId(id);
            sectionInfoVO.setExam(infoVO);
            sectionInfoVO.setExamRecords(examRecordService.list(infoVO.getId(),userId));
        }

        Integer progress = sectionProgressService.getProgressBySectionId(id, userId);

        List<SectionContentVO> sectionContentVOList = sectionContentService.getInfoListBySectionId(id);

        List<SectionTalkListVO> talks = sectionTalkService.listSome(id);

        return SectionStudyVO.builder()
                .sectionInfoVO(sectionInfoVO)
                .sectionContentVOList(sectionContentVOList)
                .talks(talks)
                .process(progress).build();
    }

    public String getNameById(String sectionId) {
        return sectionDao.lambdaQuery().select(SectionDO::getName).eq(SectionDO::getId,sectionId).one().getName();
    }

    public Integer countByCourseId(String id) {
        return sectionDao.lambdaQuery().eq(SectionDO::getCourseId,id).count();
    }

    public String getCourseIdById(String id) {
        return sectionDao.lambdaQuery().select(SectionDO::getCourseId).eq(SectionDO::getId,id).one().getCourseId();
    }

    public String getFirstId(String courseId) {
        ChapterDO one = chapterDao.lambdaQuery()
                .select(ChapterDO::getId)
                .eq(ChapterDO::getCourseId, courseId)
                .eq(ChapterDO::getSequence, 0)
                .one();
        if(one == null){
            throw new ApiException(ApiExceptionEnum.UNKNOWN_ERROR,"该课程尚未初始化");
        }else {
            return sectionDao.lambdaQuery()
                    .select(SectionDO::getId)
                    .eq(SectionDO::getChapterId,one.getId())
                    .eq(SectionDO::getSequence, 0)
                    .one().getId();
        }
    }

    public List<String> getIdsByCourseId(String courseId) {
        List<SectionDO> list = sectionDao.lambdaQuery()
                .select(SectionDO::getId)
                .eq(SectionDO::getCourseId, courseId).list();

        ArrayList<String> ids = new ArrayList<>();
        for (SectionDO sectionDO : list) {
            ids.add(sectionDO.getId());
        }
        return ids;
    }
}
